package org.hawk.gwt.ppc.introspection.impl;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.hawk.gwt.ppc.introspection.IntrospectionUtils;
import org.hawk.gwt.ppc.introspection.JavaTypeScope;

/**
 * Provides scopes and collections for some basic and primitive types.
 * 
 * @author alex.bereznevatiy@gmail.com
 *
 */
final class PrimitiveTypeScopes {
	// not for instantiation
	private PrimitiveTypeScopes(){}
	
	static final JavaTypeScope BOOLEAN = IntrospectionUtils.getType(Boolean.TYPE);
	
	static final JavaTypeScope INT = IntrospectionUtils.getType(Integer.TYPE);
	
	static final JavaTypeScope LONG = IntrospectionUtils.getType(Long.TYPE);
	
	static final JavaTypeScope FLOAT = IntrospectionUtils.getType(Float.TYPE);
	
	static final JavaTypeScope DOUBLE = IntrospectionUtils.getType(Double.TYPE);
	
	static final JavaTypeScope SHORT = IntrospectionUtils.getType(Short.TYPE);
	
	static final JavaTypeScope CHAR = IntrospectionUtils.getType(Character.TYPE);
	
	static final JavaTypeScope BYTE = IntrospectionUtils.getType(Byte.TYPE);
	
	static final JavaTypeScope VOID = IntrospectionUtils.getType(Void.TYPE);
	
	static final JavaTypeScope OBJECT = IntrospectionUtils.getType(Object.class);

	static final JavaTypeScope STRING = IntrospectionUtils.getType(String.class);
	
	static final Map<String, String> WRAPPERS;

	static {
		Map<String, String> m = new HashMap<String, String>();
		
		m.put(Boolean.class.getName(), Boolean.TYPE.getName());
		m.put(Byte.class.getName(), Byte.TYPE.getName());
		m.put(Short.class.getName(), Short.TYPE.getName());
		m.put(Character.class.getName(), Character.TYPE.getName());
		m.put(Integer.class.getName(), Integer.TYPE.getName());
		m.put(Float.class.getName(), Float.TYPE.getName());
		m.put(Long.class.getName(), Long.TYPE.getName());
		m.put(Double.class.getName(), Double.TYPE.getName());
		
		WRAPPERS = Collections.unmodifiableMap(m);
	}
		
	static final Map<String, Set<String>> ASSIGNMENTS;

	static {
		Map<String, Set<String>> m = new HashMap<String, Set<String>>();
		
		m.put(Boolean.TYPE.getName(), set(Boolean.TYPE.getName()));
		m.put(Byte.TYPE.getName(), set(Byte.TYPE.getName()));
		m.put(Short.TYPE.getName(), set(Byte.TYPE.getName(), Short.TYPE.getName()));
		m.put(Character.TYPE.getName(), set(Character.TYPE.getName()));
		m.put(Integer.TYPE.getName(), set(Byte.TYPE.getName(), Short.TYPE.getName(), Character.TYPE.getName(), Integer.TYPE.getName()));
		m.put(Float.TYPE.getName(), set(Byte.TYPE.getName(), Short.TYPE.getName(), Character.TYPE.getName(), Integer.TYPE.getName(),
				Float.TYPE.getName(), Long.TYPE.getName()));
		m.put(Long.TYPE.getName(), set(Byte.TYPE.getName(), Short.TYPE.getName(), Character.TYPE.getName(), 
				Integer.TYPE.getName(), Long.TYPE.getName()));
		m.put(Double.TYPE.getName(), set(Long.TYPE.getName(), Byte.TYPE.getName(), Short.TYPE.getName(), Character.TYPE.getName(), 
				Integer.TYPE.getName(), Long.TYPE.getName(), Float.TYPE.getName(), Double.TYPE.getName()));
		
		ASSIGNMENTS = Collections.unmodifiableMap(m);
	}
	
	static final Set<String> NUMBERS = set(Byte.TYPE.getName(), Byte.class.getName(), Short.TYPE.getName(), Short.class.getName(),
			Integer.TYPE.getName(), Integer.class.getName(), Float.TYPE.getName(), Float.class.getName(), Long.TYPE.getName(), 
			Long.class.getName(), Double.TYPE.getName(), Double.class.getName());

	private static Set<String> set(String...values) {
		return Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(values)));
	}
}

